import selectors
import socket
import json
import os

class ServerFtp(object):
    sel = selectors.DefaultSelector()

    def __init__(self):
        sock = socket.socket()
        sock.bind(('localhost', 9999))
        sock.listen(1000)
        sock.setblocking(False)
        self.sel.register(sock, selectors.EVENT_READ, self.accept)

    def accept(self, sock, mask):
        conn, addr = sock.accept()
        print('建立连接：', addr)
        conn.setblocking(False)
        self.sel.register(conn, selectors.EVENT_READ, self.conversation)

    def conversation(self, conn, mask):
        try:
            data = conn.recv(1024)
            if data:
                try:
                    cmd_dict = json.loads(data.decode())
                    action = cmd_dict['action']
                    if hasattr(self, action):
                        func = getattr(self, action)
                        func(conn, cmd_dict)
                except (UnicodeDecodeError, json.decoder.JSONDecodeError, TypeError) as e:
                    self.put_file(conn, data)
            else:
                self.sel.unregister(conn)
                conn.close()
        except ConnectionResetError as e:
            print(e)
            self.sel.unregister(conn)
            conn.close()

    def get_ack(self, conn, data):
        filesite = 'save_data'+os.sep+data['filename']
        if os.path.isfile(filesite):
            send_data = {
                'flag': 'ok',
                'filesize': os.stat(filesite).st_size,
            }
        else:
            send_data = {
                'flag': 'not'
            }
        conn.send(json.dumps(send_data).encode())

    def get_file(self, conn, data):
        filesite = 'save_data'+os.sep+data['filename']
        f = open(filesite, 'rb')
        content = f.read()
        conn.sendall(content)
        f.close()

    def put_ack(self, conn, data):
        file_site = 'save_data'+os.sep+data['filename']
        if os.path.isfile(file_site):
            conn.send(b'not')
        else:
            f = open(file_site, 'w')
            f.close()
            conn.send(b'ok')


    def put_file(self, conn, data):
        file_site = 'save_data'+os.sep+data['filename']
        f = open(file_site, 'a')
        f.write(data['content'])
        conn.send(b'ok')
